package net.lico;

import org.apache.commons.lang.StringUtils;

import java.util.*;

/**
 * 将键道可挂载智能平台的txt词库文件转成一道txt词库文件
 */
public class JD2YD {

    /**
     * 一道声母、韵母(全拼+简拼)
     */
    public static Map<String, String> shengmu = new HashMap<String, String>();
    public static Map<String, String> yunmu = new HashMap<String, String>();
    /**
     * 键道声母、韵母(全拼+简拼) —— 或声韵
     */
    public static Map<String, String> shengmuJD = new HashMap<String, String>();
    public static Map<String, String> yunmuJD = new HashMap<String, String>();
    /**
     * 键道零声母
     */
    public static Map<String, String> lingYD = new HashMap<String, String>();
    /**
     * 一道零声母
     */
    public static Map<String, String> lingJD = new HashMap<String, String>();

    /**
     * 单字全拼编码 (中文字符，编码)
     */
    public static Map<String, Set<String>> danziQuanPinMap = new HashMap<String, Set<String>>();
    /**
     * 零声母汉字集合
     */
    public static Set<String> lingShengMuSet = new HashSet<String>();
    public static Set<String> emptyChineseSet = new HashSet<String>();

    /**
     * 组合声母(ZHI,CHI)
     */
    public static List<String> zuheSM = new ArrayList<String>();

    //------------- 过程中需要参考的文件：
    //键道手心的声母韵母映射配置文件
    public static String palminput_cfg_jd = "G:\\soft\\viewer&editor\\input\\键道6挂载\\键道6挂载手心\\conf-phone-new.txt";
    //一道手心的声母韵母映射配置文件
    public static String palminput_cfg_yd = "G:\\soft\\viewer&editor\\input\\一道\\一道挂载手心\\YD-conf-phone-new.txt";
    //单字全拼编码文件
    public static String danziFile = "G:\\soft\\viewer&editor\\input\\全拼输入法汉字编码WINPY.TXT";

    //键道词库文件多合一挂载文件
//    public static String jdFile = "D:\\Program Files\\Rime_JD\\rime\\dict-palminput-0708.txt";
        public static String jdFile = "D:\\Program Files\\Rime_JD\\rime\\dict-palminput.test.txt";
//        public static String jdFile = "D:\\Program Files\\Rime_JD\\rime\\dict-palminput-0811.txt";
    //一道歌颂终结版词库——处理键道词库中 z/zh c/ch s/sh 合并后重码时的参考
    public static String yd_gesong = "G:\\soft\\viewer&editor\\input\\一道\\星空一道歌颂终结版\\rime\\dict-palminput.txt";


    static {
        //零声母一道v对应键道的x，形部分 一道e 对应 键道的 v
        lingJD.put("xs", "a");
        lingJD.put("xh", "ai");
        lingJD.put("xf", "an");
        lingJD.put("xp", "ang");
        lingJD.put("xz", "ao");
        lingJD.put("xe", "e");
        lingJD.put("xw", "ei");
        lingJD.put("xn", "en");
        lingJD.put("xr", "eng");
        lingJD.put("xj", "er");
        lingJD.put("xl", "o");
        lingJD.put("xd", "ou");

        lingYD.put("va", "a");
        lingYD.put("vh", "ai");
        lingYD.put("vj", "an");
        lingYD.put("vp", "ang");
        lingYD.put("vk", "ao");
        lingYD.put("ve", "e");
        lingYD.put("vi", "ei");
        lingYD.put("vn", "en");
        lingYD.put("vm", "eng");
        lingYD.put("vu", "er");
        lingYD.put("vo", "o");
        lingYD.put("vr", "ou");
    }

    //搜狗词库去掉三字词以上的词组
    public static final boolean isSouGou = true;
    //测试键道部分词组时，不需要拼上一道的词
    public static boolean testJD = true;

    //排序-------------
    //歌颂终结版词库
    private static List<String> ydGesongDictList = new ArrayList<String>();
    private static Map<String, List<DictModel>> referenceDictMapGroupByCHS = new HashMap<String, List<DictModel>>();
    private static Map<String, List<DictModel>> referenceDictMapGroupByCode = new HashMap<String, List<DictModel>>();
    
    static {
        try {
            initReferenceMap();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) throws Exception {

//        initReferenceMap();
        List<String> jd2YDList = convertJD2YD();

        //根据歌颂一道终结版词库来处理由键道词库转换过来的一道词库中出现的重码
        List<String> ydList = sortYDDictByGeSong(jd2YDList);
        //最终结果写入文件
        DictFileUtil.writeDictFile("G:\\soft\\viewer&editor\\input\\一道\\搜狗\\dict-0822-0.txt", ydList);

        System.out.println("完事");
    }

    /**
     * 是否为正确的全拼
     * @param sm
     * @param ym
     * @param chinese
     * @return
     */
    public static boolean isCorrectQuanPin(String sm, String ym, String chinese) {
        Set<String> codeSet = danziQuanPinMap.get(chinese);
        if (codeSet == null) {
            emptyChineseSet.add(chinese);
            return false;
        }
        if ("v".equals(ym)) {
            if (codeSet.contains(sm + "v") || codeSet.contains(sm + "u")) {
                return true;
            }
        } else {
            return codeSet.contains(sm + ym);
        }
        return false;
    }

    /** 转换键道词库为一道词库-start **/

    /**
     * 将键道词库转成一道：
     * 双拼部分：1.零声母，键道零声母引导“x”；一道零声母引导“v”。
     * 2.一般双拼处理：将键道双拼中的声母和韵母分别转换成全拼，最后将转换后的全拼结果再转成一道的双拼
     * 形码部分：一道的形和键道的形除了代表“横”的部分不一样以外（可以直接替换掉），其他是一模一样的。
     *
     * @return
     * @throws Exception
     */
    public static List<String> convertJD2YD() throws Exception {
        //键道声韵手心配置文件
        readMappingFile(palminput_cfg_jd, false);
        //一道声韵手心配置文件
        readMappingFile(palminput_cfg_yd, true);

        //开始转换
        //键道词库
        List<String> fileContentList = DictFileUtil.readDictFile(jdFile);
        List<String> resultList = new ArrayList<String>();
        //把键道的双拼编码转换为全拼编码时参考的单字全拼码表
        List<String> danziList = DictFileUtil.readDictFile(danziFile);
        for (String lineTmp : danziList) {
            if ("".equals(lineTmp) || lineTmp.length() < 2) continue;
            String dzCode = lineTmp.substring(1).trim();
            String ch = lineTmp.substring(0, 1);
            if (dzCode.startsWith("#")) {
                lingShengMuSet.add(ch);
                continue;
            }
            //zh、ch 组合声母
            if (dzCode.startsWith("zh") || dzCode.startsWith("ch")) {
                zuheSM.add(ch);
            }
            Set<String> codeList = danziQuanPinMap.get(ch);
            if (codeList == null) {
                codeList = new HashSet<String>();
                danziQuanPinMap.put(ch, codeList);
            }
            if (dzCode.indexOf(" ") != -1) {
                String[] s = dzCode.split(" ");
                for (String s1 : s) {
                    codeList.add(s1);
                }
            } else {
                codeList.add(dzCode);
            }
        }
        Set<String> addedLine = new HashSet<String>();
        for (String line : fileContentList) {
            line = line.trim();
            String[] dictStr = line.split(",");
            String[] chineseStr = line.split("=");
            String code = dictStr[0];
            String chinese = chineseStr[1].trim();
            if(chinese.length()>2)continue;
            StringBuffer result = new StringBuffer();
            //后缀，除了声韵以外的“形”部分
            String subffix = "";
            //过滤纯形字词
            if (code.startsWith("a") || code.startsWith("v") ||
                    code.startsWith("u") || code.startsWith("i") || code.startsWith("o")) {
//                    System.out.println(line);
                continue;
            }
            if (code.length() >= 4) {
                String x = code.substring(2);
                //提前将键道的“横v”笔画改成一道的e
                subffix = code.substring(4).replace("v", "e");
                boolean isSingleCode = false;
                //判断是否为超过4码的单字（第三码包含形码）——低于四码的也是一样的处理
                if (x.startsWith("a") || x.startsWith("v") || x.startsWith("u") || x.startsWith("i") || x.startsWith("o")) {
                    isSingleCode = true;
                }
                if (chinese.length() == 0) {
                    continue;
                }
                if (chinese.length() == 1) {
                    isSingleCode = true;
                }
                //跳过三码的词组
                if (isSingleCode && chinese.length() > 1) {
                    continue;
                }
                if (isSingleCode) {
                    //提前将键道的“横v”笔画改成一道的e
                    subffix = code.substring(2).replace("v", "e");
                    code = code.substring(0, 2);
                    //零声母提前转成一道的
                    String ling = getYDLingShengMu(code, chinese);
                    if (StringUtils.isNotBlank(ling)) {
                        result.append(ling.substring(0, 1)).append(",").append(ling.substring(1, 2)).append(",").append(subffix);
                    } else {
                        convertToQuanPin(code, chinese, result, subffix);
                    }
                } else {//四码
                    String syTmp = code.substring(0, 4);
                    String firstCode = syTmp.substring(0, 2);
                    String secondCode = syTmp.substring(2, 4);
                    String chinese1 = null;
                    String chinese2 = null;
                    if (chinese.length() == 2) {
                        chinese1 = chinese.substring(0, 1);
                        chinese2 = chinese.substring(1, 2);
                    }
                    //零声母提前转成一道的
                    String ling1 = getYDLingShengMu(firstCode, chinese1);
                    String ling2 = getYDLingShengMu(secondCode, chinese2);
                    if (StringUtils.isBlank(ling1)) {
                        convertToQuanPin(result, firstCode, chinese1);
                    } else {
                        //ling1
                        result.append(ling1.substring(0, 1)).append(",").append(ling1.substring(1, 2)).append(",");
                    }
                    if (StringUtils.isBlank(ling2)) {
                        convertToQuanPin(secondCode, chinese2, result, subffix);
                    } else {
                        //ling2
                        result.append(ling2.substring(0, 1)).append(",").append(ling2.substring(1, 2)).append(",").append(subffix);
                    }
                }

            } else if (code.length() > 1 && chinese.length() == 1) {//长度大于一，小于四
                subffix = code.substring(2).replace("v", "e");
                code = code.substring(0, 2);
                //零声母提前转成一道的
                String ling = getYDLingShengMu(code, chinese);
                if (StringUtils.isNotBlank(ling)) {
                    result.append(ling.substring(0, 1)).append(",").append(ling.substring(1, 2)).append(",").append(subffix);
                } else {
                    convertToQuanPin(code, chinese, result, subffix);
                }
                if (StringUtils.isBlank(result.toString())) {
//                    System.out.println(line+" empty#");
                    continue;
                } else if (result.toString().contains("null")) {
//                    System.out.println(line);
                    continue;
                } else {
//                    System.out.println(result);
                }
            } else if (code.length() == 1) {
                //有部分键道的一简字，在一道需要特殊处理
//                String orderNum = line.substring(line.indexOf("=")+1,line.indexOf(","));
//                if("1".equals(orderNum)){
//                    System.out.println(line);
//                }
                continue;
//                if (jdMap.values().contains(code)) {
//                
//                }
            } else {
                continue;
            }
            String quanPin = result.toString();
            if (StringUtils.isBlank(quanPin) ||//跳过纯形码的词 
                    quanPin.contains("null")) {//跳过键道中错误的词（会导致拼音中出现“null”）
//                System.out.println(line+" empty");
                continue;
            }
            //已经从键道词库转换好的一道单字编码
//            Set<String> convertedDZCode = new HashSet<String>();
            if (StringUtils.isNotBlank(quanPin)) {
                String[] split = quanPin.split(",");
                StringBuffer ydResult = new StringBuffer();
                if (split.length == 2) {
                    String sm = split[0];
                    String ym = split[1];
                    String codeNew = convertToYD(sm, ym);
                    ydResult.append(codeNew);
                    ydResult.append(",");
                    ydResult.append(dictStr[1]);
                } else if (split.length == 3) {//单字
                    String sm = split[0];
                    String ym = split[1];
                    String codeNew = convertToYD(sm, ym);
                    ydResult.append(codeNew);
                    ydResult.append(split[2]);
                    ydResult.append(",");
                    ydResult.append(dictStr[1]);
                } else if (split.length == 5) {//词组（带形码的）
                    ydResult.append(convertToYD(split[0], split[1]));
                    ydResult.append(convertToYD(split[2], split[3]));
                    ydResult.append(split[4]);
                    ydResult.append(",");
                    ydResult.append(dictStr[1]);
                }
                if (split.length == 4) {//词组（不带形码的）
                    ydResult.append(convertToYD(split[0], split[1]));
                    ydResult.append(convertToYD(split[2], split[3]));
                    ydResult.append(",");
                    ydResult.append(dictStr[1]);
                }
                String ydStr = ydResult.toString().trim();
                if (StringUtils.isBlank(ydStr)) continue;
                //防止重复添加
                if (addedLine.contains(ydStr)) continue;
                addedLine.add(ydStr);
                resultList.add(ydStr);
//                System.out.println(ydResult.toString().trim());
            } else {

//                System.out.println(result + " " + line);
            }
        }
        //补充在键道的一简“f”位置且被删掉的“这”字（一道z、zh都在z上，z键上有“在”了）

        /**TODO 再处理一下重码，根据歌颂终结版*/

        //补充一道（歌颂终结版词库）的一、三字词以上的

        if(!testJD) {
            for (String line : ydGesongDictList) {
                if (line.indexOf("=") == -1 || line.indexOf(",") == -1) continue;
                String chsyd = line.substring(line.indexOf(",") + 1);
                String codeyd = line.substring(0, line.indexOf("="));
                //过滤纯形字词
                if (codeyd.startsWith("a") || codeyd.startsWith("e") ||
                        codeyd.startsWith("u") || codeyd.startsWith("i") || codeyd.startsWith("o")) {
                    continue;
                }
                if ((chsyd.length() > 2 && !isSouGou)
                        || codeyd.length() == 1) {
                    StringBuilder sb = new StringBuilder();
                    String intYd = line.substring(line.indexOf("=") + 1, line.indexOf(","));
                    sb.append(codeyd).append(",").append(intYd).append("=").append(chsyd);
                    resultList.add(sb.toString());
                }
            }
            resultList.add("ze,1=这");
        }
        
        System.out.println("=======================");
        for (String s : emptyChineseSet) {
            System.out.println(s);
        }
//        String saveFile = "G:\\soft\\viewer&editor\\input\\一道\\一道挂载手心\\yd0625-1.txt";
//        DictFileUtil.writeDictFile(saveFile, resultList);
        return resultList;
    }

    /**
     * 将键道的拼音转成全拼
     *
     * @param result
     * @param firstCode
     * @param chinese
     */
    private static void convertToQuanPin(StringBuffer result, String firstCode, String chinese) {
        String sm = firstCode.substring(0, 1);
        String ym = firstCode.substring(1, 2);
        //返回结果为null 则表明这个编码有误
        String codeNew = isFei(sm, ym, chinese);
        if(codeNew == null) {
            result.append("null").append(",").append("null").append(",");
            return;
        }
        String tmp = null;
        if (!sm.equals(codeNew)) {
            tmp = codeNew;
        } else {
            tmp = getKeyByJDMapValue(shengmuJD, sm, null, chinese);
        }
        String tmp2 = getKeyByJDMapValue(yunmuJD, ym, tmp, chinese);
        if (isCorrectQuanPin(tmp, tmp2, chinese)) {
            result.append(tmp).append(",").append(tmp2).append(",");
        } else {
            result.append(tmp).append(",").append("null").append(",");
        }
    }

    /**
     * 将键道的拼音转成全拼（后面接形码）
     *
     * @param code
     * @param chinese
     * @param result
     * @param subffix 形码
     */
    private static void convertToQuanPin(String code, String chinese, StringBuffer result, String subffix) {
        String sm = code.substring(0, 1);
        String ym = code.substring(1, 2);
        //返回结果为null 则表明这个编码有误
        String codeNew = isFei(sm, ym, chinese);
        if(codeNew == null) {
            result.append("null").append(",").append("null").append(",").append(subffix);
            return;
        }
        String tmp = null;
        if (!sm.equals(codeNew)) {
            tmp = codeNew;
        } else {
            tmp = getKeyByJDMapValue(shengmuJD, sm, null, chinese);
        }
        String tmp2 = getKeyByJDMapValue(yunmuJD, ym, tmp, chinese);
        if (isCorrectQuanPin(tmp, tmp2, chinese)) {
            result.append(tmp).append(",").append(tmp2).append(",").append(subffix);
        } else {
            result.append(tmp).append(",").append("null").append(",").append(subffix);
        }
    }

    private static String convertToYD(String sm, String ym) {
        //已经提前转换好的零声母直接返回
        String ling = sm + ym;
        String tmp = lingYD.get(sm + ym);
        if (StringUtils.isNotBlank(tmp)) return ling;
        String s = shengmu.get(sm);
        String y = yunmu.get(ym);
        return s + y;
    }

    private static String getYDLingShengMu(String code, String chinese) {
        String ling = null;
        if (lingShengMuSet.contains(chinese)) {
            ling = lingJD.get(code);
            for (String ydCode : lingYD.keySet()) {
                String qpCode = lingYD.get(ydCode);
                if (StringUtils.equals(ling, qpCode)) {
                    ling = ydCode;
                    break;
                }
            }
        }
        return ling;
    }


    /**
     * 判断声母是否键道的飞键 —— 如果是的，那么返回的String将会和 firstCode不一样
     * 如果返回结果为null 则表明这个编码有误
     * @param firstCode  声母
     * @param secondCode 韵母
     * @param chinese
     * @return
     */
    private static String isFei(String firstCode, String secondCode, String chinese) {
        //飞键声母实际对应的那个全拼声母
        String newFirstCode = null;
        Set<String> codeSet = danziQuanPinMap.get(chinese);
        if (zuheSM.contains(chinese)) {
            //可能是飞键声母
            boolean flag = false;
            if ("q".equals(firstCode) || "j".equals(firstCode)) {//还会出现je 车 的飞键
                flag = true;
                if ("p".equals(secondCode) || "f".equals(secondCode) || "h".equals(secondCode) || "z".equals(secondCode) ||
                        "r".equals(secondCode) || "n".equals(secondCode) || "w".equals(secondCode) || "j".equals(secondCode)) {
                    if ("q".equals(firstCode)) {
//                        fei = true;
                        newFirstCode = "zh";
                    } else if ("j".equals(firstCode)) {
//                        fei = true;
                        newFirstCode = "ch";
                    }
                }

            } else if ("f".equals(firstCode) || "w".equals(firstCode)) {//wu fa
                flag = true;
                if ("f".equals(firstCode)) {
                    newFirstCode = "zh";
                } else if ("w".equals(firstCode)) {
                    newFirstCode = "ch";
                }
            }
            if(StringUtils.isNotBlank(newFirstCode)){
                //判断使用飞键的声母+韵母是否为这个汉字正确的读音，如果不是则说明这个字不是飞键
                String newSecondCode = getKeyByJDMapValue(yunmuJD, secondCode, newFirstCode, chinese);
//                if (newFirstCode == null && !codeSet.contains(firstCode + newSecondCode)) {
                if (/*newFirstCode == null && */!isCorrectQuanPin(newFirstCode , newSecondCode, chinese)) {
//                emptyChineseSet.add(chinese);
                    String quanpin = shengmuJD.get(newFirstCode + secondCode);
                    //处理飞键（qwfj）的飞键
                    if (StringUtils.isNotBlank(quanpin) && (quanpin.startsWith("zh") || quanpin.startsWith("ch"))) {
                        return quanpin.substring(0, 2);
                    }
                    return null;
                } else {
                    return newFirstCode;
                }
            } else {
                if(flag) {
                    String tmpSM = getKeyByJDMapValue(shengmuJD, firstCode, null, chinese);
                    System.out.println(tmpSM);
                    String newSecondCode = getKeyByJDMapValue(yunmuJD, secondCode, firstCode, chinese);
                    if (!isCorrectQuanPin(firstCode , newSecondCode, chinese)) {
                        return null;
                    }
                }
            }
        }
        //处理汉字的多音字情况且其中包含可飞键的声母（zh，ch）
        if (codeSet == null) {
            emptyChineseSet.add(chinese);
        }
        return firstCode;
    }

    /**
     * @param jdMap
     * @param code    需要处理的编码
     * @param shengmu 声母不为空，则表明当前处理的编码为韵母
     * @param chinese 中文字符
     * @return
     */
    public static String getKeyByJDMapValue(Map<String, String> jdMap, String code, String shengmu, String chinese) {
        Set<String> strings = jdMap.keySet();
        String result = null;
        boolean isRepeat = false;
        List<String> selected = new ArrayList<String>();
        String checkRepeat = null;
        for (String qpKey : strings) {
            String jp = jdMap.get(qpKey);
            if (jp != null && jp.equals(code)) {
                selected.add(qpKey);
                if (StringUtils.isNotBlank(checkRepeat)) {
                    isRepeat = true;
//                    break;
                } else {
                    checkRepeat = qpKey;
                }
            }
        }
        //出现重复的编码，从单字里面取编码
        if (isRepeat) {
            Set<String> codeSet = danziQuanPinMap.get(chinese);
            if (codeSet == null) {
                emptyChineseSet.add(chinese);
                return null;
            }
            for (String dzCode : codeSet) {
                if (StringUtils.isBlank(shengmu)) {//当前处理的就是声母
                    for (String s1 : selected) {
                        if (dzCode.startsWith(s1)) {
                            result = s1;
                            break;
                        }
                    }
                    if (StringUtils.isNotBlank(result)) break;//已经找到编码
                } else {//处理韵母
                    for (String s1 : selected) {
                        if (dzCode.startsWith(shengmu)) {
                            //处理v u的情况
                            if ("v".equals(s1) && (shengmu + "u").equals(dzCode)) {
                                result = s1;
                                break;
                            } else if ((shengmu + s1).equals(dzCode)) {
                                result = s1;
                                break;
                            }

                        }
                    }
                    if (StringUtils.isNotBlank(result)) break;//已经找到编码
                }
            }
        } else {
            result = checkRepeat;
        }
        return result;
    }

    /**
     * 初始化双拼方案声母、韵母的map
     *
     * @param filePath
     * @param isYD
     * @return
     * @throws Exception
     */
    public static void readMappingFile(String filePath, boolean isYD) throws Exception {
        List<String> dictFileContents = DictFileUtil.readDictFile(filePath);
        Map<String, String> tmpMap = null;
        //处理飞键的飞键。。 例如 je we 都表示车
        boolean jdShengyun = false;
        for (String line : dictFileContents) {
            if ("".equals(line)) continue;
            //一道可以完全的把声母和韵母分离

            if ("[声母]".equals(line)) {
                if (isYD) {
                    tmpMap = shengmu;
                } else {
                    tmpMap = shengmuJD;
                }
            } else if ("[韵母]".equals(line)) {
                if (isYD) {
                    tmpMap = yunmu;
                } else {
                    tmpMap = yunmuJD;
                }
            } else if ("[声韵]".equals(line)) {
                if (isYD) {
                } else {
                    jdShengyun = true;
                    tmpMap = shengmuJD;
                }
            }
            if (line.indexOf("=") < 1) continue;
            if (line.startsWith("po=")) break;
            String quanPin = line.substring(0, line.indexOf("="));
//            if (codeMap.get(quanPin) == null) {
            String jianPin = line.substring(line.indexOf("=") + 1);
            if (tmpMap != null) {
                if (jdShengyun) {
                    //值和键调转过来——方便使用
                    tmpMap.put(jianPin, quanPin);
                } else {
                    tmpMap.put(quanPin, jianPin);
                }

            }
//            } else {
//                System.out.println(quanPin);
//            }
        }
    }
    /** 转换键道词库为一道词库-end **/

    /**
     * 调整一道词库的词序-start
     **/
    public static void initReferenceMap() throws Exception {
        if (ydGesongDictList.size() == 0) {
            ydGesongDictList = DictFileUtil.readDictFile(yd_gesong);
        }
        for (String line : ydGesongDictList) {
            String chs = line.substring(line.indexOf(",") + 1);
            String code = line.substring(0, line.indexOf("="));
//            String chs = line.substring(line.lastIndexOf("=") + 1);
//            String code = line.substring(0, line.indexOf(","));
//            Integer num = Integer.valueOf(line.substring(line.indexOf(",") + 1, line.indexOf("=")));
            List<DictModel> modelListCHS = referenceDictMapGroupByCHS.get(chs);
            if (modelListCHS == null) {
                modelListCHS = new LinkedList<DictModel>();
                referenceDictMapGroupByCHS.put(chs, modelListCHS);
            }
            List<DictModel> modelListCode = referenceDictMapGroupByCode.get(code);
            if (modelListCode == null) {
                modelListCode = new LinkedList<DictModel>();
                referenceDictMapGroupByCode.put(code, modelListCode);
            }
            DictModel model = new DictModel();
            modelListCHS.add(model);
            modelListCode.add(model);
            model.setChs(chs);
            model.setCode(code);
            model.setInteger(Integer.parseInt(line.substring(line.indexOf("=") + 1, line.indexOf(","))));
//            model.setInteger(num);
        }
    }

    public static Map<String, List<DictModel>> putDictMapGroupByCHS(List<String> ydList) throws Exception {
        Map<String, List<DictModel>> map = new HashMap<String, List<DictModel>>();
        if (ydList == null) return map;
        for (String line : ydList) {
            String chs = line.substring(line.lastIndexOf("=") + 1);
            String code = line.substring(0, line.indexOf(","));
            Integer num = Integer.valueOf(line.substring(line.indexOf(",") + 1, line.indexOf("=")));
            List<DictModel> mapList = map.get(chs);
            if (mapList == null) {
                mapList = new LinkedList<DictModel>();
                map.put(chs, mapList);
            }
            DictModel dm = new DictModel();
            dm.setInteger(num);
            dm.setCode(code);
            dm.setChs(chs);
            mapList.add(dm);

        }
        return map;
    }

    public static Map<String, List<DictModel>> putDictMapGroupByCode(List<String> ydList) throws Exception {
        Map<String, List<DictModel>> map = new HashMap<String, List<DictModel>>();
        if (ydList == null) return map;
        for (String line : ydList) {
            String chs = line.substring(line.lastIndexOf("=") + 1);
            String code = line.substring(0, line.indexOf(","));
            Integer num = Integer.valueOf(line.substring(line.indexOf(",") + 1, line.indexOf("=")));
            List<DictModel> mapList = map.get(code);
            if (mapList == null) {
                mapList = new LinkedList<DictModel>();
                map.put(code, mapList);
            }
            DictModel dm = new DictModel();
            dm.setInteger(num);
            dm.setCode(code);
            dm.setChs(chs);
            mapList.add(dm);

        }
        return map;
    }

    /**
     * 获取一道单字编码
     * @return
     */
//    public static Map<String,List<String>> getYDSimpleCHSCodeMap(){
//        /**
//         mliuiu +   尛
//         mwovo  +   槑
//         mwovov +   槑
//         vdouvo +   熰
//         */
//    }

    /**
     * 根据歌颂终结版词库对键道转换一道词库中的重码来进行修改编码
     *
     * @param ydList 一道词组集合
     * @return
     * @throws Exception
     */
    public static List<String> sortYDDictByGeSong(List<String> ydList) throws Exception {
        //可能要处理成进来的词库集合都是不带形码的，形码部分都在此处拼接
        //待修正的一道词库
        Map<String, List<DictModel>> updateDictMap = putDictMapGroupByCode(ydList);
        Map<String, List<DictModel>> groupByCHS = putDictMapGroupByCHS(ydList);
        Iterator<String> iterator = updateDictMap.keySet().iterator();
        List<String> resultList = new ArrayList<String>();
        Set<String> sort = new HashSet<String>();
        while (iterator.hasNext()) {
//            boolean firstChoice = true;
            String code = iterator.next();
            //考虑是不是要把三码词给去掉（在加630的时候可能会有冲突）
//            if (modelList.size() == 0) continue;//可能跟后面改的有重码也说不定
            List<DictModel> editModelList = updateDictMap.get(code);
            Collections.sort(editModelList, DictModel.dictModelComparatorByReference);
            int sortNumber = 0;
            for (DictModel editModel : editModelList) {
                List<DictModel> modelList = referenceDictMapGroupByCHS.get(editModel.getChs());//chs
                //在键道中出现的字，一道歌颂终结版词库中没有出现，并且这个字的编码跟其他字重码。而且这个其他的字也出现在了歌颂终结版词库中
                //     ——    说明另外一个字的优先级比当前这个优先级要高


                ++sortNumber;
                //没有出现在一道词库中
                if (modelList == null) {
                    //TODO 在此添加形码
                    if (editModelList.size() > 1) {
//                        if (editModel.getInteger() == 1 || editModel.getInteger() == 0) {
                            editModel.setInteger(sortNumber);
//                        }
                    }
                    
                    //同码不同字
//                    List<DictModel> dictModels = referenceDictMapGroupByCode.get(editModel.getCode());
//                    if (dictModels == null || dictModels.size() == 0) continue;
////                    boolean lowPriority = false;
//                    for (DictModel dictModel : dictModels) {
//                        String tmpChs = dictModel.getChs();
//                        if (tmpChs.length() > 2) continue;
//                        //在键道词库中存在，才可能出现重码冲突
//                        if (groupByCHS.get(tmpChs) != null && groupByCHS.get(tmpChs).size() > 0) {
//                            List<DictModel> dictModels1 = groupByCHS.get(tmpChs);
//                            //键道词库中也包含这个字
//                            boolean jdDictContains = false;
//                            for (DictModel model : dictModels1) {
//                                if(model.getCode().equals(editModel.getCode())){//chs
//                                    jdDictContains = true;
//                                    break;
//                                }
//                            }
//                            if (jdDictContains && referenceDictMapGroupByCHS.get(tmpChs) != null && referenceDictMapGroupByCHS.get(tmpChs).size() > 0) {
//                                //在这加形？
//                                if(editModel.getInteger() == 1 || editModel.getInteger()==0) {
//                                    editModel.setInteger(editModel.integer + 1);
//                                }
//                                //                            lowPriority = true;
//                                break;
//                            }
//                        }
//                    }
//                    if(lowPriority) continue;
                    continue;
                }
                if (!sort.contains(editModel.getChs())) {
                    Collections.sort(modelList, DictModel.dictModelComparator);
                } else {
                    sort.add(editModel.getChs());
                }
//                if (editModel.getInteger() != 0) continue;
                DictModel matchedModel = null;//解决简码被全码覆盖的问题
                //首先匹配编码一样的
                for (DictModel dictModel : modelList) {
                    if (editModel.getCode().equals(dictModel.getCode())) {
                        matchedModel = dictModel;
                        break;
                    }
                }
                //没有匹配到再进行模糊匹配——先找码长短的
                if (matchedModel == null) {
                    //TODO 处理有三字词和全码时，优先取全码（不是6码的全码）
//                    for (DictModel dictModel : modelList) {
//                        //过滤纯形字词
//                        if (dictModel.getCode().startsWith("a") || dictModel.getCode().startsWith("e") ||
//                                dictModel.getCode().startsWith("u") || dictModel.getCode().startsWith("i") || dictModel.getCode().startsWith("o")) {
//                            continue;
//                        }
//                        if ((editModel.getCode().startsWith(dictModel.getCode()) || dictModel.getCode().startsWith(editModel.getCode()))) {
//                            editModel.setCode(dictModel.getCode());
//                            if (editModel.getInteger() != 0 && editModel.getInteger() != 1) {
//                                editModel.setInteger(dictModel.getInteger());
//                            }
//                            matchedModel = dictModel;
//                            break;
//                        }
//                    }
                    for (DictModel dictModel : modelList) {
                        //过滤纯形字词
                        if (dictModel.getCode().startsWith("a") || dictModel.getCode().startsWith("e") ||
                                dictModel.getCode().startsWith("u") || dictModel.getCode().startsWith("i") || dictModel.getCode().startsWith("o")) {
                            continue;
                        }
                        if ((editModel.getCode().startsWith(dictModel.getCode()) || dictModel.getCode().startsWith(editModel.getCode()))) {
                            editModel.setCode(dictModel.getCode());
                            if (editModel.getInteger() != 0 && editModel.getInteger() != 1) {
                                editModel.setInteger(dictModel.getInteger());
                            }
                            matchedModel = dictModel;
                            break;
                        }
                    }
                }
                //已经找到优先级最高的词
                if (matchedModel != null) {
                    modelList.remove(matchedModel);
//                    firstChoice = false;
                }

            }

        }
        //记录重码
        //编码，模型
        Map<String, List<DictModel>> repeatMap = new HashMap<String, List<DictModel>>();
        iterator = updateDictMap.keySet().iterator();
        while (iterator.hasNext()) {
            String chs = iterator.next();
            List<DictModel> editModelList = updateDictMap.get(chs);
            for (DictModel editModel : editModelList) {
                if (!"1".equals(editModel.getInteger() + "")) continue;
                List<DictModel> repeatList = repeatMap.get(editModel.getCode());
                if (repeatList == null) {
                    repeatList = new ArrayList<DictModel>();
                    repeatMap.put(editModel.getCode(), repeatList);
                }
                repeatList.add(editModel);

            }

        }

        List<DictModel> deleteList = new ArrayList<DictModel>();
        Iterator<String> iterator1 = repeatMap.keySet().iterator();
        while (iterator1.hasNext()) {
            String code = iterator1.next();
            List<DictModel> edictModelList = repeatMap.get(code);
            if (edictModelList.size() <= 1) continue;
            //在歌颂的词库里出现的编码优先级更高
            boolean found = false;
            List<DictModel> referenceModelList = new ArrayList<DictModel>();
            List<DictModel> modelListTmp = referenceDictMapGroupByCode.get(code);
            if (modelListTmp != null) {
                for (DictModel dictModelTmp : modelListTmp) {
                    if (!dictModelTmp.getCode().equals(code)) continue;
                    found = true;
                    referenceModelList.add(dictModelTmp);
                }
            }
            //都没找到，全保留了
            if (!found) continue;
            for (DictModel editModel : edictModelList) {
                DictModel matchedMode = null;
                for (DictModel referenceModel : referenceModelList) {
                    if (editModel.getCode().equals(referenceModel.getCode()) && editModel.getChs().equals(referenceModel.getChs())) {
                        matchedMode = editModel;
                        break;
                    }
                }
                if (matchedMode == null && "1".equals(editModel.getInteger() + "")) {
                    deleteList.add(editModel);
                }

            }
        }

        //TODO 暂时将重码的部分删掉（其实改一下序号也行） —— 以后再调整code
        for (DictModel deleteDictModel : deleteList) {
//            System.out.println(deleteDictModel);
            List<DictModel> modelList = updateDictMap.get(deleteDictModel.getChs());
            if (modelList != null)
                modelList.remove(deleteDictModel);
        }
        iterator = updateDictMap.keySet().iterator();
        Set<String> addedLine = new HashSet<String>();
        while (iterator.hasNext()) {
            String chs = iterator.next();
            List<DictModel> modelList = updateDictMap.get(chs);
            for (DictModel dictModel : modelList) {
                String line = dictModel.getCode() + "," + dictModel.getInteger() + "=" + dictModel.getChs();
                if (addedLine.contains(line)) continue;
                addedLine.add(line);
                resultList.add(line);
            }
        }
        return resultList;
    }

    /**
     * 调整一道词库的词序-end
     **/

    static class DictModel {
        private String chs;
        private String code;
        private int integer;

        public String getChs() {
            return chs;
        }

        public void setChs(String chs) {
            this.chs = chs;
        }

        public String getCode() {
            return code;
        }

        public void setCode(String code) {
            this.code = code;
        }

        public int getInteger() {
            return integer;
        }

        public void setInteger(int integer) {
            this.integer = integer;
        }

        @Override
        public String toString() {
            return "DictModel{" +
                    "chs='" + chs + '\'' +
                    ", code='" + code + '\'' +
                    ", integer=" + integer +
                    '}';
        }

        public static Comparator dictModelComparator;
        public static Comparator dictModelComparatorByReference;

        static {
            dictModelComparator = new Comparator<DictModel>() {
                @Override
                public int compare(DictModel o1, DictModel o2) {
                    int result = o1.getCode().compareTo(o2.getCode());
                    if (result == 0) {
                        return o1.getInteger() - o2.getInteger();
                    } else {
                        return result;
                    }
                }
            };
            dictModelComparatorByReference = new Comparator<DictModel>() {
                @Override
                public int compare(DictModel o1, DictModel o2) {
                    if ((referenceDictMapGroupByCHS.get(o1.getChs()) != null && referenceDictMapGroupByCHS.get(o1.getChs()).size() > 0)
                            && (referenceDictMapGroupByCHS.get(o2.getChs()) == null || referenceDictMapGroupByCHS.get(o2.getChs()).size() == 0)) {
                        return -1;
                    } else if ((referenceDictMapGroupByCHS.get(o2.getChs()) != null && referenceDictMapGroupByCHS.get(o2.getChs()).size() > 0)
                            && (referenceDictMapGroupByCHS.get(o1.getChs()) == null || referenceDictMapGroupByCHS.get(o1.getChs()).size() == 0)) {
                        return 1;
                    } else {
                        return o1.getInteger() - o2.getInteger();
                    }
                }
            };
        }
    }

}
